package com.keya.base.sh;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
public class RunShell {

    public static RunShellRet runShell(String desc, String[] cmds, int timeout)
            throws Exception {
        File inputFile = Files.createTempFile(UUID.randomUUID().toString(), "tmp").toFile();
        File errorFile = Files.createTempFile(UUID.randomUUID().toString(), "tmp").toFile();
        Date started = new Date();
        ProcessBuilder builder = new ProcessBuilder(cmds);
        builder.redirectOutput(inputFile);
        builder.redirectError(errorFile);
        String cmdline = String.join(" ", cmds);
        log.info(String.format("%s cmd:%s", desc, cmdline));
        Process process = builder.start();
        int exitCode = process.waitFor(timeout, TimeUnit.SECONDS) ? process.exitValue() : 100;
        if (exitCode == 100) {
            log.error(String.format("%s shell timeout", desc));
        }
        process.destroy();

        String input = loadLogFile(inputFile);
        String error = loadLogFile(errorFile);

        if (exitCode != 0) {
            log.error(String.format("%s Abnormal exit. exitcode = %d, passed = %d", desc, exitCode,
                    new Date().getTime() - started.getTime()));
        } else {
            log.info(String.format("%s finished. exitcode = %d, passed = %d", desc, exitCode,
                    new Date().getTime() - started.getTime()));
        }

        return new RunShellRet(cmdline, exitCode, input, error);
    }

    private static String loadLogFile(File logFile) {
        String content = "";
        try {
            content = FileUtils.readFileToString(logFile, StandardCharsets.UTF_8);
            if (content.length() > 62 * 1024) {
                log.warn("log file {} ({}) too long.", logFile.toString(), content.length());
                content = content.substring(content.length() - 62 * 1024);
            }
            FileUtils.forceDelete(logFile);
        } catch (Exception e) {
            log.error("读取shell log失败：" + e.getMessage());
        }
        return content;
    }
}
